//
// Created by 陶维涛 on 2021/5/29.
//

#ifndef TIMERINTERNAL_HPP
#define TIMERINTERNAL_HPP

#include <ctime>
#include <chrono>
#include <memory>
#include <functional>
#include <iostream>
#include "NetContext.hpp"

namespace TWT{
namespace Util{


using timerHander = std::function<void()>;
class TimerInternal :public std::enable_shared_from_this<TimerInternal>{
public:
    TimerInternal(NetWork::NetContext& netContext):
            timer_(netContext.getIoContext())
    {
    }

    ~TimerInternal(){
    }

    template<typename WatiHhander>
    void runOnce(const WatiHhander& hander, int waitTimer){
        timer_.expires_after(std::chrono::milliseconds(waitTimer));
        auto self{shared_from_this()};
        timer_.async_wait([&, self](const std::error_code & /*error*/) {
            hander();
        });
    }

    template<typename WatiHhander>
    void run(const WatiHhander& hander, int timeInterval){
        auto self{shared_from_this()};
        auto count = timer_.expires_at(timer_.expires_at() + std::chrono::milliseconds(timeInterval));
        timer_.async_wait([&,self, timeInterval,hander](const std::error_code& error) {
            if(!stop_){
                hander();
                run(hander, timeInterval);
            }
        });
    }

    template<typename WatiHhander>
    void runEvery(const WatiHhander& hander, int timeInterval){
        auto self{shared_from_this()};
        timer_.expires_after(std::chrono::milliseconds(timeInterval));
        timer_.async_wait([&, self, timeInterval, hander](const std::error_code & error) {
            if(!stop_){
                hander();
                run(hander, timeInterval);
            }
        });
    }

    void cancel(){
        stop_ = true;
    }
private:
    net::steady_timer timer_;
    timerHander hander_;
    bool stop_{false};
};
} //NetWork
} //TWT



#endif //TIMERINTERNAL_HPP
